home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 37 / IOPROG_37.ISO / SOFT / Multilizer.exe / disk1 / data1.cab / data1 / [Group19]VCL Source Professional / IvWReader.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-03-04  |  6.8 KB  |  330 lines

  1. unit IvWReader;
  2.  
  3. {$I IVMULTI.INC}
  4.  
  5. interface
  6.  
  7. uses
  8. {$IFDEF WIN32}
  9.   Windows,
  10. {$ELSE}
  11.   WinTypes, WinProcs,
  12. {$ENDIF}
  13.   SysUtils, IvDictio, IvReader;
  14.  
  15. const
  16.   WIDE_TAB_C: WideChar = WideChar($0009);
  17.   WIDE_LF_C: WideChar = WideChar($000A);
  18.   WIDE_CR_C: WideChar = WideChar($000D);
  19.   UTF16LE_TAG_C: WideChar = WideChar($FEFF);
  20.   UTF16BE_TAG_C: WideChar = WideChar($FFFE);
  21.  
  22. type
  23.   EIvNotUnicodeFile = class(Exception);
  24.  
  25.   TIvBaseWideReader = class(TObject)
  26.   protected
  27.     FStorageName: String;
  28.  
  29.   public
  30.     procedure Open; virtual; abstract;
  31.  
  32.     function Eof: Boolean; virtual; abstract;
  33.     function ReadLine: TIvWideString; virtual; abstract;
  34.  
  35.     property StorageName: String read FStorageName write FStorageName;
  36.   end;
  37.  
  38.   TIvWideReader = class(TIvBaseWideReader)
  39.   protected
  40.     FHandle: Integer;
  41.     FBufferSize: Integer;
  42.     FBufferIndex: Integer;
  43.     FBuffer: array[0..255] of WideChar;
  44.     FByteOrder: TIvByteOrder;
  45.  
  46.     function ReadIntoBuffer: Integer;
  47.     procedure ChangeWordByteOrder(var value: WideChar);
  48.  
  49.   public
  50.     constructor Create;
  51.     destructor Destroy; override;
  52.  
  53.     procedure Open; override;
  54.     procedure Close;
  55.  
  56.     function Eof: Boolean; override;
  57.     function ReadLine: TIvWideString; override;
  58.  
  59.     property ByteOrder: TIvByteOrder read FByteOrder;
  60.   end;
  61.  
  62.   TIvResourceWideReader = class(TIvBaseWideReader)
  63.   protected
  64.     FBuffer: PWideChar;
  65.     FBufferIndex: Integer;
  66.     FBufferSize: Integer;
  67.  
  68.   public
  69.     constructor Create;
  70.  
  71.     procedure Open; override;
  72.     function Eof: Boolean; override;
  73.     function ReadLine: TIvWideString; override;
  74.   end;
  75.  
  76. implementation
  77.  
  78. constructor TIvWideReader.Create;
  79. begin
  80.   inherited Create;
  81.   FHandle := 0;
  82.   FByteOrder := ivboLittleEndian;
  83. end;
  84.  
  85. destructor TIvWideReader.Destroy;
  86. begin
  87.   Close;
  88.   inherited Destroy;
  89. end;
  90.  
  91. procedure TIvWideReader.ChangeWordByteOrder(var value: WideChar);
  92. begin
  93.   value :=
  94.     WideChar(((Word(value) and $00FF) shl 8) or
  95.     ((Word(value) and $FF00) shr 8));
  96. end;
  97.  
  98. function TIvWideReader.ReadIntoBuffer: Integer;
  99. begin
  100.   FBufferIndex := 0;
  101.   FBufferSize := FileRead(FHandle, FBuffer, SizeOf(FBuffer)) div SizeOf(WideChar);
  102.   Result := FBufferSize;
  103. end;
  104.  
  105. procedure TIvWideReader.Open;
  106. var
  107.   c: WideChar;
  108. begin
  109.   FHandle := FileOpen(FStorageName, fmOpenRead);
  110.   if FHandle <= 0 then
  111.     raise EInOutError.Create('Could not open the file ' + FStorageName);
  112.  
  113.   if (FileRead(FHandle, c, SizeOf(c)) < SizeOf(c)) or ((c <> UTF16LE_TAG_C) and ((c <> UTF16BE_TAG_C))) then
  114.   begin
  115.     FileClose(FHandle);
  116.     raise EIvNotUnicodeFile.Create('Not a Unicode file');
  117.   end
  118.   else if c = UTF16LE_TAG_C then
  119.     FByteOrder := ivboLittleEndian
  120.   else
  121.     FByteOrder := ivboBigEndian;
  122.  
  123.   FBufferIndex := 0;
  124.   FBufferSize := 0;
  125. end;
  126.  
  127. procedure TIvWideReader.Close;
  128. begin
  129.   if FHandle > 0 then
  130.   begin
  131.     FileClose(FHandle);
  132.     FHandle := 0;
  133.     FBufferIndex := 0;
  134.     FBufferSize := 0;
  135.   end;
  136. end;
  137.  
  138. function TIvWideReader.Eof: Boolean;
  139. begin
  140.   if (FBufferSize = 0) or (FBufferIndex = FBufferSize) then
  141.     ReadIntoBuffer;
  142.   Result := FBufferSize = 0;
  143. end;
  144.  
  145. {$IFDEF IVWIDE}
  146. function TIvWideReader.ReadLine: WideString;
  147. var
  148.   c: WideChar;
  149. begin
  150.   Result := '';
  151.   while True do
  152.   begin
  153.     if FBufferIndex = FBufferSize then
  154.     begin
  155.       if ReadIntoBuffer = 0 then
  156.         Break;
  157.     end;
  158.  
  159.     c := FBuffer[FBufferIndex];
  160.     if ByteOrder = ivboBigEndian then
  161.       ChangeWordByteOrder(c);
  162.     Inc(FBufferIndex);
  163.  
  164.     if c = WIDE_LF_C then
  165.       // Unix style text file (only LF at the end of line)
  166.  
  167.       Break
  168.     else if c = WIDE_CR_C then
  169.     begin
  170.       // MSDOS style text file (both CR and LF at the end of line)
  171.  
  172.       if FBufferIndex = FBufferSize then
  173.       begin
  174.         if ReadIntoBuffer = 0 then
  175.           Break;
  176.       end;
  177.  
  178.       Inc(FBufferIndex);
  179.       Break;
  180.     end
  181.     else
  182.       Result := Result + WideString(c);
  183.   end;
  184. end;
  185. {$ELSE}
  186. function TIvWideReader.ReadLine: TIvWideString;
  187. var
  188.   c: WideChar;
  189.   len, size: Integer;
  190. begin
  191.   len := 0;
  192.   size := 256;
  193.   Result := SysAllocStringLen(nil, size);
  194.   while True do
  195.   begin
  196.     if FBufferIndex = FBufferSize then
  197.     begin
  198.       if ReadIntoBuffer = 0 then
  199.         Break;
  200.     end;
  201.  
  202.     c := FBuffer[FBufferIndex];
  203.     if ByteOrder = ivboBigEndian then
  204.       ChangeWordByteOrder(c);
  205.     Inc(FBufferIndex);
  206.  
  207.     if c = WIDE_LF_C then
  208.       // Unix style text file (only LF at the end of line)
  209.  
  210.       Break
  211.     else if c = WIDE_CR_C then
  212.     begin
  213.       if FBufferIndex = FBufferSize then
  214.       begin
  215.         if ReadIntoBuffer = 0 then
  216.           Break;
  217.       end;
  218.  
  219.       Inc(FBufferIndex);
  220.       Break;
  221.     end
  222.     else
  223.     begin
  224.       if len >= size then
  225.       begin
  226.         size := 3*size div 2;
  227.         SysReAllocStringLen(Result, Result, size);
  228.       end;
  229.       Result[len] := c;
  230.       Inc(len);
  231.     end;
  232.   end;
  233.   Result[len] := WideChar(0);
  234. end;
  235. {$ENDIF}
  236.  
  237. constructor TIvResourceWideReader.Create;
  238. begin
  239.   inherited Create;
  240.   FBuffer := nil;
  241.   FBufferIndex := 0;
  242.   FBufferSize := 0;
  243. end;
  244.  
  245. procedure TIvResourceWideReader.Open;
  246. var
  247.   resource: HRSRC;
  248.   handle: HGLOBAL;
  249. begin
  250.   resource := FindResource(HInstance, PChar(FStorageName), MULTILIZER_RES_TYPE_C);
  251.   if resource = 0 then
  252.     raise EInOutError.Create('Could not open the resource ' + FStorageName);
  253.  
  254.   handle := LoadResource(HInstance, resource);
  255.   if handle = 0 then
  256.     raise EInOutError.Create('Could not open the resource ' + FStorageName);
  257.  
  258.   FBuffer := LockResource(handle);
  259.   FBufferIndex := 0;
  260.   FBufferSize := SizeofResource(HInstance, resource);
  261. end;
  262.  
  263. function TIvResourceWideReader.Eof: Boolean;
  264. begin
  265.   Result := FBufferIndex = FBufferSize;
  266. end;
  267.  
  268. {$IFDEF IVWIDE}
  269. function TIvResourceWideReader.ReadLine: WideString;
  270. var
  271.   c: WideChar;
  272. begin
  273.   Result := '';
  274.   while True do
  275.   begin
  276.     c := FBuffer[FBufferIndex];
  277.     Inc(FBufferIndex);
  278.  
  279.     if c = WIDE_LF_C then
  280.       // Unix style text file (only LF at the end of line)
  281.  
  282.       Break
  283.     else if c = WIDE_CR_C then
  284.     begin
  285.       Inc(FBufferIndex);
  286.       Break;
  287.     end
  288.     else
  289.       Result := Result + WideString(c);
  290.   end;
  291. end;
  292. {$ELSE}
  293. function TIvResourceWideReader.ReadLine: TIvWideString;
  294. var
  295.   c: WideChar;
  296.   len, size: Integer;
  297. begin
  298.   len := 0;
  299.   size := 256;
  300.   Result := SysAllocStringLen(nil, size);
  301.   while True do
  302.   begin
  303.     c := FBuffer[FBufferIndex];
  304.     Inc(FBufferIndex);
  305.  
  306.     if c = WIDE_LF_C then
  307.       // Unix style text file (only LF at the end of line)
  308.  
  309.       Break
  310.     else if c = WIDE_CR_C then
  311.     begin
  312.       Inc(FBufferIndex);
  313.       Break;
  314.     end
  315.     else
  316.     begin
  317.       if len >= size then
  318.       begin
  319.         size := 3*size div 2;
  320.         SysReAllocStringLen(Result, Result, size);
  321.       end;
  322.       Result[len] := c;
  323.       Inc(len);
  324.     end;
  325.   end;
  326. end;
  327. {$ENDIF}
  328.  
  329. end.
  330.